var MobileSelect = (function() {

  function getClass(dom,string) {
    return dom.getElementsByClassName(string);
  }

  //构造器
  function MobileSelect(config) {
    this.mobileSelect;
    this.wheelsData = config.wheels;
    this.jsonType =  false;
    this.jsonData = [];
    this.checkDataType();
    this.renderWheels(this.wheelsData);
    this.displayJson = [];
    this.cascade = false;
    this.startY;
    this.moveEndY;
    this.moveY;
    this.oldMoveY;
    this.offset = 0;
    this.offsetSum = 0;
    this.oversizeBorder;
    this.curDistance = [];
    this.clickStatus = false;

    this.init(config);
  }

  MobileSelect.prototype = {
    constructor: MobileSelect,
    init: function(config){
      var _this = this;

      _this.trigger = document.querySelector(config.trigger);
      _this.wheel = getClass(_this.mobileSelect,'wheel');   //wheel 数组
      _this.slider = getClass(_this.mobileSelect,'selectContainer'); // slider 数组
      _this.wheels = _this.mobileSelect.querySelector('.wheels');   //wheels
      _this.liHeight = _this.mobileSelect.querySelector('li').offsetHeight;
      _this.ensureBtn = _this.mobileSelect.querySelector('.ensure');
      _this.closeBtn = _this.mobileSelect.querySelector('.cancel');
      _this.grayLayer = _this.mobileSelect.querySelector('.grayLayer');
      _this.popUp = _this.mobileSelect.querySelector('.content');
      _this.callback = config.callback ? config.callback : function(){};
      _this.transitionEnd = config.transitionEnd ? config.transitionEnd : function(){};
      _this.initPosition = config.position ? config.position : [];
      _this.titleText = config.title ? config.title : '';

      _this.trigger.style.cursor='pointer';
      _this.setTitle(_this.titleText);
      _this.checkCascade();

      if (_this.cascade) {
        _this.initCascade();
      }

      //定位 初始位置
      if(_this.initPosition.length == 0){
        for(var i=0; i<_this.slider.length; i++){
          _this.initPosition.push(0);
        }
      }

      _this.setCurDistance(_this.initPosition);
      _this.addListenerAll();

      //按钮监听
      _this.closeBtn.addEventListener('click',function(){
        _this.mobileSelect.classList.remove('mobileSelect-show');
      });

      _this.ensureBtn.addEventListener('click',function(){
        _this.mobileSelect.classList.remove('mobileSelect-show');
        var tempValue ='';
        for(var i=0; i<_this.wheel.length; i++){
          i==_this.wheel.length-1 ? tempValue += _this.getValue(i) : tempValue += _this.getValue(i)+' ';
        }
        _this.trigger.innerHTML = tempValue;
        _this.callback(_this.getIndexArr(),_this.getJson());
      });

      _this.trigger.addEventListener('click',function(){
        _this.mobileSelect.classList.add('mobileSelect-show');
      });
      _this.grayLayer.addEventListener('click',function(){
        _this.mobileSelect.classList.remove('mobileSelect-show');
      });
      _this.popUp.addEventListener('click',function(){
        event.stopPropagation();
      });

      _this.fixRowStyle(); //修正列数
    },

    setTitle: function(string){
      var _this = this;
      _this.titleText = string;
      _this.mobileSelect.querySelector('.title').innerHTML = _this.titleText;
    },

    renderWheels: function(wheelsData){
      var _this = this;
      _this.mobileSelect = document.createElement("div");
      _this.mobileSelect.className = "mobileSelect";
      _this.mobileSelect.innerHTML =
        '<div class="grayLayer"></div>'+
        '<div class="content">'+
        '<div class="btnBar">'+
        '<div class="fixWidth">'+
        '<div class="cancel">取消</div>'+
        '<div class="title"></div>'+
        '<div class="ensure">选择</div>'+
        '</div>'+
        '</div>'+
        '<div class="panel">'+
        '<div class="fixWidth">'+
        '<div class="wheels">'+
        '</div>'+
        '<div class="selectLine"></div>'+
        '<div class="shadowMask"></div>'+
        '</div>'+
        '</div>'+
        '</div>';
      document.body.appendChild(_this.mobileSelect);

      //根据数据长度来渲染

      var tempHTML='';
      for(var i=0; i<wheelsData.length; i++){ //列
        tempHTML += '<div class="wheel"><ul class="selectContainer">';
        if(_this.jsonType){
          for(var j=0; j<wheelsData[i].data.length; j++){ //行
            tempHTML += '<li data-id="'+wheelsData[i].data[j].id+'">'+wheelsData[i].data[j].value+'</li>';
          }
        }else{
          for(var j=0; j<wheelsData[i].data.length; j++){ //行
            tempHTML += '<li>'+wheelsData[i].data[j]+'</li>';
          }
        }
        tempHTML += '</ul></div>';
      }
      _this.mobileSelect.querySelector('.wheels').innerHTML = tempHTML;
    },

    addListenerAll: function(){
      var _this = this;
      for(var i=0; i<_this.slider.length; i++){
        //手势监听
        (function (i) {
          _this.addListenerWheel(_this.wheel[i], i);
          _this.addListenerLi(i);
        })(i);
      }
    },

    addListenerWheel: function(theWheel, index){
      var _this = this;
      theWheel.addEventListener('touchstart', function () {
        _this.touch(event, this.firstChild, index);
      },false);
      theWheel.addEventListener('touchend', function () {
        _this.touch(event, this.firstChild, index);
      },false);
      theWheel.addEventListener('touchmove', function () {
        _this.touch(event, this.firstChild, index);
      },false);

      //PC拖拽监听
      theWheel.addEventListener('mousedown', function () {
        _this.dragClick(event, this.firstChild, index);
      },false);
      theWheel.addEventListener('mousemove', function () {
        _this.dragClick(event, this.firstChild, index);
      },false);
      theWheel.addEventListener('mouseup', function () {
        _this.dragClick(event, this.firstChild, index);
      },true);
    },

    addListenerLi:function(sliderIndex){
      var _this = this;
      var curWheelLi = _this.slider[sliderIndex].getElementsByTagName('li');
      for(var j=0; j<curWheelLi.length;j++){
        (function (j) {
          curWheelLi[j].addEventListener('click',function(){
            _this.singleClick(this, j, sliderIndex);
          },false);
        })(j);
      }
    },

    checkDataType: function(){
      var _this = this;
      if(typeof(_this.wheelsData[0].data[0])=='object'){
        _this.jsonType = true;
        _this.jsonData = _this.wheelsData[0].data;
      }
    },

    checkCascade: function(){
      var _this = this;
      if(_this.jsonType){
        var node = _this.wheelsData[0].data;
        for(var i=0; i<node.length; i++){
          if('childs' in node[i] && node[i].childs.length > 0){
            _this.cascade = true;
            break;
          }
        }
      }else{
        _this.cascade = false;
      }
    },

    initCascade: function(){
      var _this = this;
      _this.displayJson.push(_this.generateArrData(_this.jsonData));
      _this.checkArrDeep(_this.jsonData[0]);
      //console.log('将要显示的json:');
      //console.log(_this.displayJson);
      _this.updateWheels();
    },

    generateArrData: function (targetArr) {
      var tempArr = [];
      for(var i=0; i<targetArr.length; i++){
        tempArr.push({
          "id": targetArr[i].id,
          "value": targetArr[i].value
        });
      }
      return tempArr;
    },

    checkArrDeep: function (parent) { //检测子节点深度  修改 displayJson
      var _this = this;
      if ('childs' in parent && parent.childs.length > 0) {
        _this.displayJson.push(_this.generateArrData(parent.childs)) ; //生成子节点数组
        _this.checkArrDeep(parent.childs[0]);//检测下一个子节点
      }
    },

    checkRange: function(index, posIndexArr){
      var _this = this;
      var deleteNum = _this.displayJson.length-1-index;
      for(var i=0; i<deleteNum; i++){
        _this.displayJson.pop(); //修改 displayJson
      }
      var resultNode;
      for (var i = 0; i <= index; i++){
        if (i == 0)
          resultNode = _this.jsonData[posIndexArr[0]];
        else {
          resultNode = resultNode.childs[posIndexArr[i]];
        }
      }
      _this.checkArrDeep(resultNode);
      //console.log(_this.displayJson);
      _this.updateWheels();
      _this.fixRowStyle();
      _this.setCurDistance(_this.resetPostion(index, posIndexArr));
    },

    resetPostion: function(index, posIndexArr){
      var _this = this;
      var tempPosArr = posIndexArr;
      var tempCount;
      if(_this.slider.length > posIndexArr.length){
        tempCount = _this.slider.length - posIndexArr.length;
        for(var i=0; i<tempCount; i++){
          tempPosArr.push(0);
        }
      }else if(_this.slider.length < posIndexArr.length){
        tempCount = posIndexArr.length - _this.slider.length;
        for(var i=0; i<tempCount; i++){
          tempPosArr.pop();
        }
      }
      for(var i=index+1; i< tempPosArr.length; i++){
        tempPosArr[i] = 0;
      }
      return tempPosArr;
    },

    updateWheels: function(){
      var _this = this;
      //删除多余的wheel
      if(_this.wheel.length > _this.displayJson.length){
        var count = _this.wheel.length - _this.displayJson.length;
        for(var i=0; i<count; i++){
          _this.wheels.removeChild(_this.wheel[_this.wheel.length-1]);
        }
      }

      for(var i=0; i<_this.displayJson.length; i++){ //列
        (function (i) {
          var tempHTML='';
          if(_this.wheel[i]){
            //console.log('插入Li');
            for(var j=0; j<_this.displayJson[i].length; j++){ //行
              tempHTML += '<li data-id="'+_this.displayJson[i][j].id+'">'+_this.displayJson[i][j].value+'</li>';
            }
            _this.slider[i].innerHTML = tempHTML;

          }else{
            var tempWheel = document.createElement("div");
            tempWheel.className = "wheel";
            tempHTML = '<ul class="selectContainer">';
            for(var j=0; j<_this.displayJson[i].length; j++){ //行
              tempHTML += '<li data-id="'+_this.displayJson[i][j].id+'">'+_this.displayJson[i][j].value+'</li>';
            }
            tempHTML += '</ul>';
            tempWheel.innerHTML = tempHTML;

            _this.addListenerWheel(tempWheel, i);
            _this.wheels.appendChild(tempWheel);
          }
          _this.addListenerLi(i);
        })(i);
      }
    },

    updateWheel: function(sliderIndex, data){
      var _this = this;
      var tempHTML='';
      for(var j=0; j<data.length; j++){
        tempHTML += '<li>'+data[j]+'</li>'
      }
      _this.slider[sliderIndex].innerHTML = tempHTML;
      _this.addListenerLi(sliderIndex);
    },

    fixRowStyle: function(){
      var _this = this;
      var width = (100/_this.wheel.length).toFixed(2);
      for(var i=0; i<_this.wheel.length; i++){
        _this.wheel[i].style.width = width+'%';
      }
    },

    getIndex: function(distance){
      return Math.round((2*this.liHeight-distance)/this.liHeight);
    },

    getIndexArr: function(){
      var _this = this;
      var temp = [];
      for(var i=0; i<_this.curDistance.length; i++){
        temp.push(_this.getIndex(_this.curDistance[i]));
      }
      return temp;
    },

    getJson: function(){
      var _this = this;
      var temp = [];
      var positionArr = _this.getIndexArr();
      if(_this.cascade){
        for(var i=0; i<_this.wheel.length; i++){
          temp.push(_this.displayJson[i][positionArr[i]]);
        }
      }
      else if(_this.jsonType){
        for(var i=0; i<_this.curDistance.length; i++){
          temp.push(_this.wheelsData[i].data[_this.getIndex(_this.curDistance[i])]);
        }
      }else{
        for(var i=0; i<_this.curDistance.length; i++){
          temp.push(_this.getValue(i));
        }
      }
      return temp;
    },

    calcDistance: function(index){
      return 2*this.liHeight-index*this.liHeight;
    },

    setCurDistance: function(indexArr){
      var _this = this;
      var temp = [];
      for(var i=0; i<_this.slider.length; i++){
        temp.push(_this.calcDistance(indexArr[i]));
        _this.movePosition(_this.slider[i],temp[i]);
      }
      _this.curDistance = temp;
    },

    fixPosition: function(distance){
      return -(this.getIndex(distance)-2)*this.liHeight;
    },

    movePosition: function(theSlider, distance){
      theSlider.style.webkitTransform = 'translate3d(0,' + distance + 'px, 0)';
      theSlider.style.transform = 'translate3d(0,' + distance + 'px, 0)';
    },

    locatePostion: function(index, posIndex){
      this.curDistance[index] = this.calcDistance(posIndex);
      this.movePosition(this.slider[index],this.curDistance[index]);
    },

    updateCurDistance: function(theSlider, index){
      this.curDistance[index] = parseInt(theSlider.style.transform.split(',')[1]);
    },

    getDistance:function(theSlider){
      return parseInt(theSlider.style.transform.split(',')[1]);
    },

    getValue: function(sliderIndex){
      var _this = this;
      var index = _this.getIndex(_this.curDistance[sliderIndex]);
      return _this.slider[sliderIndex].getElementsByTagName('li')[index].innerHTML;
    },

    touch: function(event, theSlider, index){
      var _this = this;
      event = event || window.event;
      switch(event.type){
        case "touchstart":
          _this.startY = event.touches[0].clientY;
          _this.oldMoveY = _this.startY;
          break;

        case "touchend":

          _this.moveEndY = event.changedTouches[0].clientY;
          _this.offsetSum = _this.moveEndY - _this.startY;

          //修正位置
          _this.updateCurDistance(theSlider, index);
          _this.curDistance[index] = _this.fixPosition(_this.curDistance[index]);
          _this.movePosition(theSlider, _this.curDistance[index]);
          _this.oversizeBorder = -(theSlider.getElementsByTagName('li').length-3)*_this.liHeight;


          //反弹
          if(_this.curDistance[index] + _this.offsetSum > 2*_this.liHeight){
            _this.curDistance[index] = 2*_this.liHeight;
            setTimeout(function(){
              _this.movePosition(theSlider, _this.curDistance[index]);
            }, 100);

          }else if(_this.curDistance[index] + _this.offsetSum < _this.oversizeBorder){
            _this.curDistance[index] = _this.oversizeBorder;
            setTimeout(function(){
              _this.movePosition(theSlider, _this.curDistance[index]);
            }, 100);
          }


          _this.transitionEnd(_this.getIndexArr(),_this.getJson());

          if(_this.cascade){
            var tempPosArr = _this.getIndexArr();
            tempPosArr[index] = _this.getIndex(_this.curDistance[index]);
            _this.checkRange(index, tempPosArr);
          }

          break;

        case "touchmove":
          event.preventDefault();
          _this.moveY = event.touches[0].clientY;
          _this.offset = _this.moveY - _this.oldMoveY;

          _this.updateCurDistance(theSlider, index);
          _this.curDistance[index] = _this.curDistance[index] + _this.offset;
          _this.movePosition(theSlider, _this.curDistance[index]);
          _this.oldMoveY = _this.moveY;
          break;
      }
    },

    dragClick: function(event, theSlider, index){
      var _this = this;
      event = event || window.event;
      switch(event.type){
        case "mousedown":
          _this.startY = event.clientY;
          _this.oldMoveY = _this.startY;
          _this.clickStatus = true;
          break;

        case "mouseup":

          _this.moveEndY = event.clientY;
          _this.offsetSum = _this.moveEndY - _this.startY;

          //修正位置
          _this.updateCurDistance(theSlider, index);
          _this.curDistance[index] = _this.fixPosition(_this.curDistance[index]);
          _this.movePosition(theSlider, _this.curDistance[index]);
          _this.oversizeBorder = -(theSlider.getElementsByTagName('li').length-3)*_this.liHeight;


          //反弹
          if(_this.curDistance[index] + _this.offsetSum > 2*_this.liHeight){
            _this.curDistance[index] = 2*_this.liHeight;
            setTimeout(function(){
              _this.movePosition(theSlider, _this.curDistance[index]);
            }, 100);

          }else if(_this.curDistance[index] + _this.offsetSum < _this.oversizeBorder){
            _this.curDistance[index] = _this.oversizeBorder;
            setTimeout(function(){
              _this.movePosition(theSlider, _this.curDistance[index]);
            }, 100);
          }

          _this.clickStatus = false;
          _this.transitionEnd(_this.getIndexArr(),_this.getJson());
          if(_this.cascade){
            var tempPosArr = _this.getIndexArr();
            tempPosArr[index] = _this.getIndex(_this.curDistance[index]);
            _this.checkRange(index, tempPosArr);
          }
          break;

        case "mousemove":
          event.preventDefault();
          if(_this.clickStatus){
            _this.moveY = event.clientY;
            _this.offset = _this.moveY - _this.oldMoveY;

            _this.updateCurDistance(theSlider, index);
            _this.curDistance[index] = _this.curDistance[index] + _this.offset;
            _this.movePosition(theSlider, _this.curDistance[index]);
            _this.oldMoveY = _this.moveY;
          }
          break;
      }
    },

    singleClick: function(theLi, index, sliderIndex){
      var _this = this;
      if(_this.cascade){
        var tempPosArr = _this.getIndexArr();
        tempPosArr[sliderIndex] = index;
        _this.checkRange(sliderIndex, tempPosArr);

      }else{
        _this.curDistance[sliderIndex] = (2-index)*_this.liHeight;
        _this.movePosition(theLi.parentNode, _this.curDistance[sliderIndex]);
      }
    }

  };

  return MobileSelect;
})();

export default MobileSelect
